from datetime import UTC, datetime

import pytest
import pytest_asyncio
from fastapi.testclient import TestClient

from src.crud.vehicle_crud import create_fuel_record
from src.database import get_db
from src.main import app
from src.models.vehicle_model import GasStationType, VehicleFuelRecord
from tests.conftest import override_get_db


@pytest.fixture(scope="session")
def client():
    """创建测试客户端 - session级别,避免重复创建"""
    app.dependency_overrides[get_db] = override_get_db
    with TestClient(app) as test_client:
        yield test_client
    app.dependency_overrides.clear()


@pytest.fixture(scope="function")
def admin_token(client):
    """获取管理员token - function级别,确保每个测试都有独立的数据"""
    register_data = {
        "username": "admin_user",
        "email": "admin@example.com",
        "password": "adminpassword",
        "full_name": "管理员用户",
        "family_name": "测试家庭",
    }
    client.post("/api/v1/auth/register", json=register_data)

    login_data = {"username": "admin_user", "password": "adminpassword"}
    login_response = client.post("/api/v1/auth/login", json=login_data)
    token = login_response.json()["access_token"]
    return token


@pytest.fixture
def family_member(client, admin_token):
    headers = {"Authorization": f"Bearer {admin_token}"}

    # 创建一个成员
    member_data = {
        "username": "member_user",
        "email": "member@example.com",
        "password": "memberpassword",
        "full_name": "普通成员用户",
        "role": "member",  # 明确指定角色
    }
    res = client.post("/api/v1/family-members/", json=member_data, headers=headers)
    return res.json()


@pytest.fixture
def family_child(client, admin_token):
    headers = {"Authorization": f"Bearer {admin_token}"}

    # 创建一个成员
    member_data = {
        "username": "child_user",
        "email": "child@example.com",
        "password": "childpassword",
        "full_name": "普通成员用户",
        "role": "child",
    }
    res = client.post("/api/v1/family-members/", json=member_data, headers=headers)
    return res.json()


@pytest.fixture(scope="function")
def member_token(client, family_member: dict):
    """获取普通成员token - function级别,确保每个测试都有独立的数据"""

    login_data = {
        "username": family_member.get("username"),
        "password": "memberpassword",
    }
    login_response = client.post("/api/v1/auth/login", json=login_data)
    token = login_response.json()["access_token"]
    return token


@pytest.fixture(scope="function")
def child_token(client, family_child: dict):
    """获取普通成员token - function级别,确保每个测试都有独立的数据"""

    login_data = {
        "username": family_child.get("username"),
        "password": "childpassword",
    }
    login_response = client.post("/api/v1/auth/login", json=login_data)
    token = login_response.json()["access_token"]
    return token


@pytest_asyncio.fixture
async def create_test_fuel_record():
    """创建测试加油记录的fixture"""

    async def _create_test_fuel_record(
        family_id: int,
        current_mileage: float = 1000.0,
        fuel_amount: float = 40.0,
        fuel_cost: float = 300.0,
        fuel_price: float = 7.5,
        gas_station_type: GasStationType = GasStationType.SINOPEC,
        notes: str = "测试加油记录",
        refuel_date: datetime | None = None,
    ) -> VehicleFuelRecord:
        if refuel_date is None:
            refuel_date = datetime.now(UTC)

        fuel_record_data = {
            "family_id": family_id,
            "current_mileage": current_mileage,
            "fuel_amount": fuel_amount,
            "fuel_cost": fuel_cost,
            "fuel_price": fuel_price,
            "gas_station_type": gas_station_type,
            "notes": notes,
            "refuel_date": refuel_date,
        }

        # 获取数据库会话
        from src.database import AsyncSessionLocal

        async with AsyncSessionLocal() as session:
            record = await create_fuel_record(
                session=session,
                vehicle_id=1,  # 默认车辆ID
                current_mileage=current_mileage,
                fuel_amount=fuel_amount,
                fuel_cost=fuel_cost,
                fuel_price=fuel_price,
                gas_station_type=gas_station_type,
                refuel_date=refuel_date,
                family_id=family_id,
                notes=notes,
            )
            await session.commit()
            return record

    return _create_test_fuel_record
